<?php
/*
 *  Maniter: A webbased business managment tool.
 *  Copyright (C) 2007  Dimitri Michaux <dimitri.michaux@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * pdfpurchase.class.php, Maniter
 * 
 * This class can be used to display purchaseorders/offers as pdf-files.
 * To do this we use the FPDF libray (http://www.fpdf.org/).
 *
 * @author Dimitri Michaux
 * @version 0.1
 * @package maniter_classes
 */

require_once(_PATH_TO_JIBA.'fpdf.php');
require_once('purchase.class.php');
require_once(_PATH_TO_JIBA.'contactinfo.class.php');

define('EURO',chr(128));

class PdfPurchase extends FPDF{
	
	/**
	 * Enter description here...
	 *
	 * @var Purchase
	 */
	private $_purchases;
	
	/**
	 * Enter description here...
	 *
	 * @var ContactInfo
	 */
	private $_clientInfo;
	private $_number;
	private $_date;
	private $_dueDate;
	private $_subTotal;
	private $_total;
	private $_advance = 0;
	
	private $_footerText;
	private $_headerText;
	
	/**
	 * Enter description here...
	 *
	 * @var String array('vat%'=>'total')
	 */
	private $_vatPerVat;
	
	/**
	 * A collection of characters where we can split on
	 * 
	 * In case user was stupid and didn't add spaces after a punctuation
	 */
	private $_punctuation = array( ' ', ',', '.', '-', '?', '!' );
	
	public function __construct()
	{
	   parent::FPDF();
	}
	
	public function Output(){
		$this->SetAutoPageBreak(false, $this->tMargin);
		
		$this->AddPage();
		$this->_pageHeader();
		
		if( isset($this->_headerText) )
			$this->_headerText();
		
		if( isset($this->_number) && isset($this->_date) )
			$this->_orderInfo();
			
		$this->_showTable();	
		$this->_totalTable();
		
		if( isset($this->_footerText) )
			$this->_footerText();
		
		parent::Output();
	}
	
	public function setPurchases( &$purchases){
		$this->_purchases =& $purchases;
	}
	
	public function setAdvance( $advance ){
		$this->_advance = $advance;
	}
	
	public function setClientInfo( &$info ){
		$this->_clientInfo =& $info;
	}
	
	public function setNumber( $number ){
		$this->_number = $number;
	}
	
	public function setDate( $date ){
		$this->_date = $date;
	}
	
	public function setDueDate( $date ){
		$this->_dueDate = $date;
	}
	
	public function setFootText( &$text ){
		$this->_footerText =& $text;
	}
	
	public function setHeaderText( &$text ){
		$this->_headerText =& $text;
	}
	
	public function setVatPerVat( $array ){
		$this->_vatPerVat = $array;
	}
	
	public function setSubtotal( $sub ){
		$this->_subTotal = $sub;
	}
	
	public function setTotal( $total ){
		$this->_total = $total;
	}
	
	private function _pageHeader(){
		
		$owner = PurchaseList::getOwnerInfo();
		$items = array('Company','Name','Street','City','Phone','Fax','VatNr','BankAccount','Website','Email');
		
		//logo
		$this->Image(company_logo,10,8,140);
		
		//company info
		$this->SetFont('Arial','',10);
		
		$this->SetXY(155,8);
		
		//print info
		foreach($items as $item){
			$function = "get".$item;
			$info = $owner->$function();
			
			if($info!="")
				$this->Cell(70,4,$info, 0, 2);
		}
		
		//client info
		$this->Cell(70,4,"", 0, 2);
		$this->SetFont('Arial','B',10);
		$this->Cell(70,4,"Gegevens klant:", 0, 2);
		$this->SetFont('Arial','',10);
		
		//print info
		foreach($items as $item){
			$function = "get".$item;
			$info = $this->_clientInfo->$function();
			
			if($info!="")
				$this->Cell(70,4,$info, 0, 2);
		}
		
		$this->SetFont('Arial','',10);
		
		//don't make anything overlap
		if( $this->GetY() < 69 )
			$this->SetY( 75 );
		else
			$this->SetY( $this->GetY() + 6 );
	}
	
	private function _orderInfo(){
		//purchase order info
		$this->setX(10);
		$this->SetFont('Arial','B',14);
		$this->Cell(100,8,"Factuur: " . $this->_number , 1, 0, 'C');
		$this->Cell(90,8,"Datum: " . $this->_date, 1, 1, 'C');
		
		//empty cell
		$this->Cell(0,4,"",0,1);
	}
	
	private function _tableHeader(){
		$this->SetFont('Arial','B',14);
		
		//header for table
		$this->Cell(100,8,"Omschrijving", 1, 0, 'C');
		$this->Cell(17,8,"Aantal", 1, 0, 'C');
		$this->Cell(29,8,"Prijs", 1, 0, 'C');
		$this->Cell(29,8,"Totaal", 1, 0, 'C');
		$this->Cell(15,8,"Btw", 1, 1, 'C');
		
		$this->_tableSpacer();
	}
	
	private function _showTable(){
		$this->_tableHeader();
		
		foreach( $this->_purchases as &$purchase ){
			$this->_tableAddPurchase($purchase);
			$this->_tableSpacer();
		}
		
		//line at bottom of table
		$this->Cell(190,0,"", 'T', 1 );
	}
	
	/**
	 * Enter description here...
	 *
	 * @param Purchase $purchase
	 */
	private function _tableAddPurchase( &$purchase ){
		$this->SetFont('Arial','',12);
		$discriptionLines = $this->_splitString( $purchase->getDescription() );
		
		//does it all fit on the page?
		if( (count($discriptionLines)*6)+2+$this->bMargin+$this->GetY() > $this->fh  ){
			//line at bottom of table
			$this->Cell(190,8,"", 'T', 1 );
			//if not make a new one
			$this->AddPage();
			//draw table header on new page
			$this->_tableHeader();
			//continue like nothing happend
		}
		
		$this->SetFont('Arial','',12);
		
		//fill in the line
		$first = true;	//first line?
		foreach( $discriptionLines as $description ){
			$this->Cell(100,6,$description, 'LR', 0, 'L' );
			
			//first time?
			//fill in all the info
			if($first){
				$this->Cell( 17,6,$purchase->printAmount(), 'LR', 0, 'C' );
				
				if($purchase->printPrice()!=''){ //euro sign
					$this->Cell( 4,6,EURO, 'L', 0, 'R' );
					$this->Cell( 25,6,$purchase->printPrice(), 'R', 0, 'R' );
				}else
					$this->Cell( 29,6,$purchase->printPrice(), 'LR', 0, 'R' );
				
				if($purchase->printSubtotal()!=''){ //euro sign
					$this->Cell( 4,6,EURO, 'L', 0, 'R' );
					$this->Cell( 25,6,$purchase->printSubtotal(), 'R', 0, 'R' );
				}else
					$this->Cell( 29,6,$purchase->printPrice(), 'LR', 0, 'R' );
				
				$this->Cell( 15,6,$purchase->printVat(), 'LR', 1, 'C' );
				
				$first = false;
			}
			else //second time or more we only need blank lines
			{
				$this->Cell( 17, 6,"", 'LR', 0, 'C' );
				$this->Cell( 29, 6,"", 'LR', 0, 'R' );
				$this->Cell( 29, 6,"", 'LR', 0, 'R' );
				$this->Cell( 15, 6,"", 'LR', 1, 'C' );
			}
		}
	}
	
	private function _totalTable(){
		//empty cell
		$this->Cell(0,4,"",0,1);
		
		//if it all doesn't fit on this pag add a new one
		if( (count($this->_vatPerVat)*8+24+$this->GetY()+$this->bMargin) > $this->fh )
			$this->AddPage();
		
		$this->SetX( 127 );
		
		//subtotal
		$this->SetFont('Arial','B',14);
		$this->Cell( 29, 8, "Subtotaal:", 'LRT', 0, 'L' ); 
		$this->Cell( 4, 8, EURO, 'LT', 0, 'R' );//euro sign
		$this->Cell( 40, 8, $this->_subTotal, 'RT', 1, 'R' );
		
		//vat amounts
		$this->SetFont('Arial','',14);
		foreach( $this->_vatPerVat as $vat => $subTotal ){
			$this->SetX( 127 );
			$this->Cell( 29, 8, "BTW $vat:", 'LR', 0, 'L' );
			$this->Cell( 4, 8, EURO, 'L', 0, 'R' );//euro sign
			$this->Cell( 40, 8, $subTotal, 'R', 1, 'R' );
		}
		
		$this->SetFont('Arial','B', 14);
		
		//advance
		if( $this->_advance != 0 ){
			$this->SetX( 127 );
			$this->Cell( 29, 8, "Voorschot:", 'LR', 0, 'L' );
			$this->Cell( 4, 8, EURO, 'L', 0, 'R' );//euro sign
			$this->Cell( 40, 8, $this->_advance, 'R', 1, 'R' );
		}
		
		//total
		$this->SetX( 127 );
		$this->Cell( 29, 8, "Totaal:", 1, 0, 'L' );
		$this->Cell( 4, 8, EURO, 'LTB', 0, 'R' );//euro sign
		$this->Cell( 40, 8, $this->_total, 'RTB', 1, 'R' );
	}
		
	private function _headerText(){
		$this->SetX( 10 );
		$this->SetFont('Arial','',12);
		
		$lines = $this->_splitString( $this->_headerText, $this->fw-20 );
		
		foreach ( $lines as $line )
			$this->Cell( 0, 6, $line, 0, 1 );
			
		//empty cell
		$this->Cell(0,4,"",0,1);
	}
	
	private function _footerText(){
		//empty cell
		$this->Cell(0,4,"",0,1);
		
		$this->SetX( 10 );
		$this->SetFont('Arial','',12);
		

		$lines = $this->_splitString( $this->_footerText, $this->fw-20 );
		
		if( (count($lines)*6)+2+$this->bMargin+$this->GetY() > $this->fh  )
			$this->AddPage();
		
		foreach ( $lines as $line )
			$this->Cell( 0, 6, $line, 0, 1 );
	}

	private function _splitString( $str, $width=100 ){	
		$lines = array();
		
		//echo "+BEGIN: $str<br/>\n";
		
		if( strstr($str,"\n") ){
		//	echo "++has newlines<br/>\n";
			
			$realLines = explode("\n",$str);
			
		//	echo "++SPLITTING IN:\n<br/>";
		//	foreach( $realLines as $line ){
		//		echo "+++IN: $line<br/>\n";
		//	}
			
			foreach( $realLines as $line ){
		//		echo "+++DOING LINE: $line<br/>\n";
				$lines = array_merge( $lines, $this->_splitString($line,$width) );
			}
			
		}else{
		//         echo "++SPLITTING.<br/>\n";
			 do{
			 	$res = $this->_getStringExcess($str, $width);
			 	$lines[] = $res[0];
			 }while( ($str=$res[1]) != "" );
		}
		
		//echo "++SPLITTED IN:<br/>\n";
		//foreach( $lines as $line ){
		//	echo "+++: $line<br/>\n";
		//}
		
		return $lines;
	}
	
	//returns the string and it's excess
	private function _getStringExcess( $str, $width=100 ){
          $excess = "";
          
          while( $this->GetStringWidth($str) > $width ){
            
            $pos = array(); //contains all the possitions
            foreach( $this->_punctuation as $sign )
              $pos[] = strrpos( rtrim($str,implode($this->_punctuation)), $sign );
            
            //remove dublicate values
            array_unique( $pos );
            //we only need the last occurance
            rsort( $pos );
            
            //lets make sure there is a possition
            if( $pos[0]<strlen($str)-1 && $pos[0]!==false )
              $splitPos = $pos[0]+1;
            elseif( $pos[1]<strlen($str)-1 && $pos[1]!==false )
              $splitPos = $pos[1]+1;
            else
              $splitPos = strlen($str)-2;
            
            //split the string
            $excess = substr( $str, $splitPos ).$excess; //last part of the string
            $str = substr( $str, 0, $splitPos );    //first part of the string
          }
          
          return array( $str, $excess );
	}
	
	//add some more spacing between lines
	private function _tableSpacer(){
		$this->Cell(100,2,"",'LR', 0);
		$this->Cell(17,2,"", 'LR', 0);
		$this->Cell(29,2,"", 'LR', 0);
		$this->Cell(29,2,"", 'LR', 0);
		$this->Cell(15,2,"", 'LR', 1);
	}
}
?>